package com.xqboss.apps.service.equipment;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.Assert;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xqboss.apps.domain.equipment.EquipmentUpgradeConfig;
import com.xqboss.apps.domain.equipment.EquipmentUpgradeConfigBreak;
import com.xqboss.apps.domain.equipment.EquipmentUpgradeConfigCoefficient;
import com.xqboss.apps.domain.equipment.EquipmentUpgradeTemplate;
import com.xqboss.apps.dto.equipment.EquipmentUpgradeConfigCoefficientDto;
import com.xqboss.apps.dto.equipment.EquipmentUpgradeConfigDto;
import com.xqboss.apps.dto.equipment.EquipmentUpgradeHoldDto;
import com.xqboss.apps.dto.equipment.EquipmentUpgradeTemplateDto;
import com.xqboss.apps.enums.equipment.UpgradeConfigCoefficientEnum;
import com.xqboss.apps.mapper.equipment.EquipmentUpgradeTemplateMapper;
import com.xqboss.common.exception.ServiceException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;

/**
 * 装备升级加点-升级模板服务
 *
 * @author wangcong
 * @date 2023-11-23
 */
@Service
public class EquipmentUpgradeTemplateService extends ServiceImpl<EquipmentUpgradeTemplateMapper, EquipmentUpgradeTemplate> {

    @Autowired
    private EquipmentUpgradeConfigService equipmentUpgradeConfigService;

    @Autowired
    private EquipmentUpgradeConfigCoefficientService equipmentUpgradeConfigCoefficientService;

    @Autowired
    private EquipmentUpgradeConfigBreakService equipmentUpgradeConfigBreakService;

    /**
     * 新增装备升级加点模版
     *
     * @param params
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public boolean add(EquipmentUpgradeTemplateDto params) {
        //校验昵称是否唯一
        LambdaQueryWrapper<EquipmentUpgradeTemplate> wp = new LambdaQueryWrapper<>();
        wp.eq(EquipmentUpgradeTemplate::getTitle, params.getTitle());
        if (Objects.nonNull(params.getId())) {
            wp.ne(EquipmentUpgradeTemplate::getId, params.getId());
        }
        wp.last("limit 1");
        EquipmentUpgradeTemplate one = getOne(wp);
        if (Objects.nonNull(one)) {
            throw new ServiceException("模版名称重复");
        }
        //校验最小等级 < 最大等级
        boolean b = params.getConfig().stream().anyMatch(item -> item.getMinLevel() >= item.getMaxLevel());
        if (b) {
            throw new ServiceException("最小等级需小于最大等级");
        }
        // 校验配置中的模式1模式2不能同时开启
        boolean res = params.getConfig().stream().anyMatch(item -> item.getModeOneEnable() && item.getModeTwoEnable());
        if (res) {
            throw new ServiceException("模式1模式2不能同时开启");
        }
        // 模式1和模式2不能同时关闭
        boolean res1 = params.getConfig().stream().anyMatch(item -> !item.getModeOneEnable() && !item.getModeTwoEnable());
        if (res1) {
            throw new ServiceException("模式1模式2不能同时关闭");
        }
        // 如果模式一开启，校验模式一的参数是否为空
        if (params.getConfig().stream().anyMatch(item -> item.getModeOneEnable() && (item.getTalentCoefficient() == null || item.getBreakageGuarantee() == null || item.getIntegralMaxRatio() == null || item.getIntegralMinRatio() == null
                || CollUtil.isEmpty(item.getBlemishCoefficient()) || CollUtil.isEmpty(item.getBreakageCoefficient())))) {
            throw new ServiceException("模式一参数不能为空");
        }
        // 如果模式二开启，校验模式二的参数是否为空
        if (params.getConfig().stream().anyMatch(item -> item.getModeTwoEnable() && (item.getBreakHotBeans() == null || item.getBreakProtectNum() == null || item.getBreakSuccessRatio() == null || item.getEvolveHotBeansRatio() == null))) {
            throw new ServiceException("模式二参数不能为空");
        }
        // 如果模式二开启，校验热豆消耗与保底次数不能为负数
        if (params.getConfig().stream().anyMatch(item -> item.getModeTwoEnable() && (item.getBreakHotBeans().compareTo(BigDecimal.ZERO) < 0 || item.getBreakProtectNum().compareTo(0) < 0
                || item.getBreakSuccessRatio().compareTo(BigDecimal.ZERO) < 0 || item.getEvolveHotBeansRatio().compareTo(BigDecimal.ZERO) < 0))) {
            throw new ServiceException("热豆消耗、保底次数、成功概率、进化消耗不能为负数");
        }

        EquipmentUpgradeTemplate template = new EquipmentUpgradeTemplate();
        template.setTitle(params.getTitle());
        template.setId(params.getId());
//        template.setMaxLevel();
        this.saveOrUpdate(template);

        //添加模版配置
        List<EquipmentUpgradeConfigDto> config = params.getConfig();
        for (EquipmentUpgradeConfigDto item : config) {
            EquipmentUpgradeConfig equipmentUpgradeConfig = new EquipmentUpgradeConfig();
            equipmentUpgradeConfig.setUpgradeTemplateId(template.getId());
            equipmentUpgradeConfig.setId(item.getId());
            equipmentUpgradeConfig.setMinLevel(item.getMinLevel());
            equipmentUpgradeConfig.setMaxLevel(item.getMaxLevel());
            equipmentUpgradeConfig.setAttribute(item.getAttribute());
            equipmentUpgradeConfig.setMinExpRatio(item.getMinExpRatio());
            equipmentUpgradeConfig.setTalentCoefficient(item.getTalentCoefficient());
            equipmentUpgradeConfig.setBreakageGuarantee(item.getBreakageGuarantee());
            equipmentUpgradeConfig.setIntegralMinRatio(item.getIntegralMinRatio());
            equipmentUpgradeConfig.setIntegralMaxRatio(item.getIntegralMaxRatio());
            equipmentUpgradeConfig.setDetectHold(item.getDetectHold());
            equipmentUpgradeConfig.setIntegralMinExp(item.getIntegralMinExp());
            equipmentUpgradeConfig.setDetectNftId(item.getDetectNftId());
            equipmentUpgradeConfig.setModeOneEnable(item.getModeOneEnable());
            equipmentUpgradeConfig.setModeTwoEnable(item.getModeTwoEnable());
            equipmentUpgradeConfig.setBreakHotBeans(item.getBreakHotBeans());
//            equipmentUpgradeConfig.setBreakMaterialId(item.getBreakMaterialId());
            equipmentUpgradeConfig.setBreakProtectNum(item.getBreakProtectNum());
            equipmentUpgradeConfig.setBreakSuccessRatio(item.getBreakSuccessRatio());
            equipmentUpgradeConfig.setEvolveHotBeansRatio(item.getEvolveHotBeansRatio());
            equipmentUpgradeConfigService.saveOrUpdate(equipmentUpgradeConfig);

            //添加配置的 瑕疵 爆率系数
            if (CollUtil.isNotEmpty(item.getBlemishCoefficient())) {
                List<EquipmentUpgradeConfigCoefficientDto> blemish = item.getBlemishCoefficient();
                List<EquipmentUpgradeConfigCoefficient> blemishCoefficient = BeanUtil.copyToList(blemish, EquipmentUpgradeConfigCoefficient.class);
                blemishCoefficient.forEach(bl -> {
                    bl.setUpgradeConfigId(equipmentUpgradeConfig.getId());
                    bl.setType(UpgradeConfigCoefficientEnum.BLEMISH);
                });
                equipmentUpgradeConfigCoefficientService.saveOrUpdateBatch(blemishCoefficient);
            }

            //添加配置的 破损 爆率系数
            if (CollUtil.isNotEmpty(item.getBreakageCoefficient())) {
                List<EquipmentUpgradeConfigCoefficientDto> breakage = item.getBreakageCoefficient();
                List<EquipmentUpgradeConfigCoefficient> breakageCoefficient = BeanUtil.copyToList(breakage, EquipmentUpgradeConfigCoefficient.class);
                breakageCoefficient.forEach(br -> {
                    br.setUpgradeConfigId(equipmentUpgradeConfig.getId());
                    br.setType(UpgradeConfigCoefficientEnum.BREAKAGE);
                });
                equipmentUpgradeConfigCoefficientService.saveOrUpdateBatch(breakageCoefficient);
            }

            //添加配置的 突破材料
            if (CollUtil.isNotEmpty(item.getBreakMaterials())) {
                List<EquipmentUpgradeConfigBreak> breakMaterials = item.getBreakMaterials();
                breakMaterials.forEach(bm -> {
                    bm.setUpgradeConfigId(equipmentUpgradeConfig.getId());
                });
                equipmentUpgradeConfigBreakService.saveOrUpdateBatch(breakMaterials);
            }
        }
        return true;
    }

    /**
     * 获取装备升级加点详情
     *
     * @param id
     * @return
     */
    public EquipmentUpgradeTemplateDto details(Long id) {
        EquipmentUpgradeTemplateDto vo = new EquipmentUpgradeTemplateDto();

        //获取模版
        EquipmentUpgradeTemplate template = getById(id);
        Assert.notNull(template, "模版不存在");
        BeanUtil.copyProperties(template, vo);

        //获取模版配置

        List<EquipmentUpgradeConfigDto> copyToList = equipmentUpgradeConfigService.getBaseMapper().listByQuery(template.getId());

        vo.setConfig(copyToList);

        //获取配置系数
        for (EquipmentUpgradeConfigDto item : vo.getConfig()) {
            //瑕疵
            List<EquipmentUpgradeConfigCoefficient> blemishList = equipmentUpgradeConfigCoefficientService.list(new LambdaQueryWrapper<EquipmentUpgradeConfigCoefficient>()
                    .eq(EquipmentUpgradeConfigCoefficient::getUpgradeConfigId, item.getId())
                    .eq(EquipmentUpgradeConfigCoefficient::getType, UpgradeConfigCoefficientEnum.BLEMISH));
            List<EquipmentUpgradeConfigCoefficientDto> blCoefficient = BeanUtil.copyToList(blemishList, EquipmentUpgradeConfigCoefficientDto.class);
            item.setBlemishCoefficient(blCoefficient);
            //破损
            List<EquipmentUpgradeConfigCoefficient> bremishList = equipmentUpgradeConfigCoefficientService.list(new LambdaQueryWrapper<EquipmentUpgradeConfigCoefficient>()
                    .eq(EquipmentUpgradeConfigCoefficient::getUpgradeConfigId, item.getId())
                    .eq(EquipmentUpgradeConfigCoefficient::getType, UpgradeConfigCoefficientEnum.BREAKAGE));
            List<EquipmentUpgradeConfigCoefficientDto> brCoefficient = BeanUtil.copyToList(bremishList, EquipmentUpgradeConfigCoefficientDto.class);
            item.setBreakageCoefficient(brCoefficient);
            //突破材料
            List<EquipmentUpgradeConfigBreak> breakList = equipmentUpgradeConfigBreakService.list(new LambdaQueryWrapper<EquipmentUpgradeConfigBreak>()
                    .eq(EquipmentUpgradeConfigBreak::getUpgradeConfigId, item.getId()));
            item.setBreakMaterials(breakList);
        }
        return vo;
    }

    /**
     * 删除升级-配置
     *
     * @param ids
     * @return
     */
    public boolean delConfig(Long[] ids) {
        boolean b = equipmentUpgradeConfigService.removeBatchByIds(Arrays.asList(ids));
        Assert.isTrue(b, "删除配置失败");
        return b;
    }

    /**
     * 删除配置-系数
     *
     * @param ids
     * @return
     */
    public boolean delConfigCoefficient(Long[] ids, int delType) {
        if (delType == 0) {
            boolean b = equipmentUpgradeConfigCoefficientService.removeBatchByIds(Arrays.asList(ids));
            Assert.isTrue(b, "删除配置-系数失败");
            return b;
        } else if (delType == 1) {
            boolean b = equipmentUpgradeConfigBreakService.removeBatchByIds(Arrays.asList(ids));
            Assert.isTrue(b, "删除配置-突破材料失败");
            return b;
        } else {
            throw new ServiceException("删除类型错误");
        }
//        boolean b = equipmentUpgradeConfigCoefficientService.removeBatchByIds(Arrays.asList(ids));
//        Assert.isTrue(b, "删除配置-系数失败");
//        return b;
    }

    /**
     * 是否检测持仓
     *
     * @param params
     * @return
     */
    public boolean updateDetectHold(EquipmentUpgradeHoldDto params) {
        if (params.getType() == 1) {
            // 检测模式开关不能同时开启，并且也不能同时关闭
            if (params.getModeOneEnable() && params.getModeTwoEnable()) {
                throw new ServiceException("升级模式1和升级模式2不能同时开启");
            }
            if (!params.getModeOneEnable() && !params.getModeTwoEnable()) {
                throw new ServiceException("升级模式1和升级模式2不能同时关闭");
            }
            boolean b = equipmentUpgradeConfigService.update(new LambdaUpdateWrapper<EquipmentUpgradeConfig>()
                    .set(EquipmentUpgradeConfig::getModeOneEnable, params.getModeOneEnable())
                    .set(EquipmentUpgradeConfig::getModeTwoEnable, params.getModeTwoEnable())
                    .eq(EquipmentUpgradeConfig::getId, params.getId()));
            Assert.isTrue(b, "修改模式开关失败");
            return b;
        } else if (params.getType() == 0) {
            boolean b = equipmentUpgradeConfigService.update(new LambdaUpdateWrapper<EquipmentUpgradeConfig>()
                    .set(EquipmentUpgradeConfig::getDetectHold, params.getDetectHold())
                    .eq(EquipmentUpgradeConfig::getId, params.getId()));
            Assert.isTrue(b, "修改持仓状态失败");
            return b;
        }
        throw new ServiceException("修改类型错误");
    }
}
